package com.kitty.game.role.model;

import com.kitty.common.cache.RedisService;
import com.kitty.common.db.BaseEntityGame;
import com.kitty.common.db.Db4PlayerService;
import com.kitty.common.model.Pos;
import com.kitty.common.utils.SpringUtils;
import com.kitty.cross.login.model.CrossInfo;
import com.kitty.game.achieve.common.SendAchieve;
import com.kitty.game.activity.model.user.RoleActivity;
import com.kitty.game.config.ShapePen;
import com.kitty.game.confirm.model.RoleConfirm;
import com.kitty.game.drop.model.user.RoleDrop;
import com.kitty.game.equip.model.EquipBox;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.child.model.ChildInfo;
import com.kitty.game.friend.model.FriendBox;
import com.kitty.game.function.model.RoleFunction;
import com.kitty.game.guard.model.GuardBox;
import com.kitty.game.item.ItemDataPool;
import com.kitty.game.item.config.ChangeCard;
import com.kitty.game.jiutian.MSGJiuTianRespMasterInfo;
import com.kitty.game.mail.MailBox;
import com.kitty.game.market.model.MarketTransactionBox;
import com.kitty.game.party.model.Party;
import com.kitty.game.pet.model.PetBox;
import com.kitty.game.player.model.PkInfoBox;
import com.kitty.game.player.model.PlayerExtendBox;
import com.kitty.game.player.serializer.PlayerSerializerUtil;
import com.kitty.game.safeLock.service.SafeService;
import com.kitty.game.skill.model.SkillBox;
import com.kitty.game.statistics.model.RoleDailyStats;
import com.kitty.game.talk.model.RoleTalk;
import com.kitty.game.task.model.user.RoleTask;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.TimeUtil;
import com.kitty.common.model.Reason;
import com.kitty.mina.message.MessagePusher;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.nutz.lang.util.NutMap;

import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Default;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Index;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.entity.annotation.TableIndexes;

import java.text.SimpleDateFormat;
import java.util.*;

@Table("t_role")
@Setter
@Getter
@TableIndexes({@Index(fields = {"roleId"}, unique = false),
        @Index(fields = {"uid"}, unique = false),
        @Index(fields = {"sid"}, unique = false),
        @Index(fields = {"name"}, unique = false),
        @Index(fields = {"isReceive"}, unique = false)})
@JsonIgnoreProperties(ignoreUnknown =true)
@Slf4j
public class Role extends BaseEntityGame<Long> {
    public Object getOfflineNotice;
    @Id(auto = false)
    private int roleId;//角色id
    @Column
    private Long uid;//面板ID20位长度
    @Column
    private String sid;//账户ID
    @Column
    private String name;//角色名称
    @Column
    private short str;//力量
    @Column
    private int phyPower;//物理伤害
    @Column
    private short con;//体质
    @Column
    private int currLife;//当前气血
    @Column
    private int defense;//防御
    @Column
    private short wiz;//灵力
    @Column
    private boolean lockexp;//锁定经验
    @Column
    private int siver;//银币3
    @Column
    private int money;//金币
    @Column
    @Comment("首饰精华")
    private int jewelryEssence;
    @Column
    private int voucher;//代金券
    @Column
    @Default(value = "1")
    private short level = 1;
    @Column
    private short dex;//敏捷
    @Column
    private int magPower;//法术伤害
    @Column
    private int currMana;//当前法力值
    @Column
    private int speed;//速度
    @Column
    private short parry;//闪避
    @Column
    private short polar;//门派 相性
    @Column
    private short metal;//金相
    @Column
    private short wood;//木相
    @Column
    private short water;//水相
    @Column
    private short fire;//火相
    @Column
    private short earth;//土相
    @Column
    private short lastAttrib;//剩余属性
    @Column
    private String distName;//区名称
    @Column
    private short lastPolar;//剩余相性
    @Column
    private short currStamina;//当前体力
    @Column
    private short maxStamina;//最大体力
    @Column
    private long taoPoint;//道行
    @Column
    private long monthTaoPoint; //月道行点数
    @Column
    private long prevMonthTaoPoint; // 上月道行点数
    @Column
    private int pot;//潜能
    @Column
    private byte gender;//性别1男2女
    @Column
    private long partyId;//帮派ID
    @Column
    private long prevPartyId; // 之前加入帮派ID
    @Column
    private int reputation;//声望
    @Column
    private short roleIcon;//角色图标
    @Column
    private int totalScore;//战绩
    @Column
    private int exp;//升级所需经验
    @Column
    private int guiqi; //所拥有的鬼气
    @Column
    private String fixedTeam; //所在固定队
    @Column
    private int saveLife;//储备血量
    @Column
    private int saveMana;//储备法力
    @Column
    private int saveLoyalty;

    @Column
    private Date createTime;
    @Column
    private Date updateTime;
    @Column
    private long enterTime;//进入游戏的时间
    @Column
    @Comment("五行中奖存款")
    private int wuxingBankMoney;
    @Column
    @Comment("使用代金券")
    private boolean useVoucher;
    @Column
    @Comment("登录计次")
    private int logins;//
    @Column
    @Comment("VIP类型")
    private byte vipType;
    @Column
    @Comment("VIP到期时间")
    private int expireTime;
    @Column
    @Comment("VIP每日领取状态")
    private boolean isReceive;
    @Column
    @Comment("驱魔香开关")
    private boolean avoidMonster;
    @Column
    @Comment("自动战斗开关")
    private byte autoFight;
    @Column
    @Comment("激活称谓")
    private String currTitle;
    @Column
    @Comment("骑乘坐骑ID")
    private int mount;
    @Column
    @Comment("骑乘坐骑Icon")
    private int mountIcon;
    @Column
    @Comment("骑乘坐骑姿势")
    private int mountPosture;
    @Column
    @Comment("骑乘移动速度")
    private int moveSpeed;
    @Column
    @Comment("摆摊收入")
    private long stallCash;//金钱
    @Column
    @Comment("珍宝收入")
    private long stallGold;//元宝
    @Comment("购买游戏币")
    @Default("{}")
    @ColDefine(width = 1024)
    private NutMap gold2money;
    @Column
    @Comment("道具状态")
    @Default("{}")
    @ColDefine(width = 1024)
    private NutMap propsStatus;

    @Column
    @Comment("免死次数")
    private short noDeath;
    @Column
    @Comment("时装外观Icon")
    private int fasionIcon;
    @Column
    @Comment("特效Icon")
    private int effectIcon;
    @Column
    @Comment("自定义时装Icon")
    private String customFasion;
    @Column
    @Comment("使用自定义")
    private boolean isCustom;
    @Column
    @Comment("隐藏坐骑")
    private boolean hideMount;
    @Column
    @Comment("仓库存钱")
    private int storeMoney;
    @Column
    @Comment("鉴定进度")
    private short equipIdentify;
    @Column
    @Comment("封号时间")
    private long lockTime;
    @Column
    @Comment("坐标数据")
    private Pos pos = new Pos();

    private List<NutMap> shouts = new ArrayList<>();
    @Column
    @Comment("禁言时间")
    @Default("0")
    private long wordTime;
    @Column
    @Comment("true禁止交易")
    @Default("0")
    private boolean banTrade;
    @Column
    @Comment("首饰强化的次数")
    private int jewelryStrengthenCount;
    @Column
    @Comment("累计充值记录")
    @Default("0")
    private int totalCharge;



    @Column
    @Comment("装备页")
    private short equipPage;

    @Column
    @Comment("武器ICON")
    private int weaponIcon;
    @Column
    @Comment("套装发光ICON")
    private int suitLightId;
    @Column
    @Comment("套装的ID")
    private int suitId;

    @Column
    @Comment("变身卡仓库的size")
    private short cardSize = 15;
/*在线状态*/
    @Column
    @Comment("在线状态")
    private int on_line = 0;

    /**
     * 变身卡名称
     */
    @Column
    private String changeCardName;

    @Column
    private long changeCardExpireTime;
    /**
     * 九曲玲珑变身
     */
    @Column
    private String shapePenKeyName;

    @Column
    private int shapePenExpireTime;

    private long sessionId;

    private boolean unlock;//本次登录是否验证过密码
    private int mijingcount;
    @Column
    private int mijingjifen;
    @Column
    private int nice;
    private int niceszhi = Integer.MAX_VALUE;

    private byte zmLevel = 0;
    private byte ymType = 0;
    /**
     * 玩家任务
     */
    private RoleTask task = new RoleTask();

    @Column
    @ColDefine(customType = "longtext")
    private String taskJson;

    /**
     * 正在进行对话
     */
    private RoleTalk talk = new RoleTalk();

    /**
     * 玩家确认框
     */
    private RoleConfirm confirm;

    /**
     * 玩家的功能
     */
    private RoleFunction funcs = new RoleFunction();

    @Column
    @ColDefine(customType = "longtext")
    private String funcsJson;

    /**
     * 玩家每日重置时间
     */
    @Column
    private long dailyFiveResetTime;

    /**
     * 玩家每周重置时间
     */
    @Column
    private long weeklyResetTime;

    /**
     * 玩家每月重置时间
     */
    @Column
    private long monthResetTime;

    /**
     * 宠物
     */
    private PetBox petBox = new PetBox();

    @Column
    @ColDefine(customType = "longtext")
    private String petBoxJson;

    /**
     * 技能
     */
    private SkillBox skillBox = new SkillBox();

    /**
     * 装备
     */
    private EquipBox equipBox = new EquipBox();

    @Column
    @ColDefine(customType = "longtext")
    private String skillBoxJson;

    @Column
    @ColDefine(customType = "longtext")
    private String equipBoxJson;

    /**
     * 安全锁
     */
    @Column
    private String SafePasswd;

    /**
     * 安全锁强制解锁开始时间
     */
    @Column
    private int SafePasswdResetStartTime;

    /**
     * 活动
     */
    private RoleActivity activity = new RoleActivity();

    @Column
    @ColDefine(customType = "longtext")
    private String activityJson;


    /**
     * 魂窍数据
     */
    @Column
    @ColDefine(customType = "longtext")
    private String hunqiaoJson;

    /**
     * 邮箱
     */
    private MailBox mailBox = new MailBox();

    @Column
    @ColDefine(customType = "longtext")
    private String mailBoxJson;

    /**
     * 数据杂项仓库
     */
    private PlayerExtendBox extendBox;

    @Column
    @ColDefine(customType = "longtext")
    private String extendBoxJson;

    private MarketTransactionBox transactionBox;

    @Column
    @ColDefine(customType = "longtext")
    private String transactionBoxJson;


    private PkInfoBox pkInfoBox = new PkInfoBox();

    @Column
    @ColDefine(customType = "longtext")
    private String pkInfoBoxJson;

    private RoleDailyStats dailyStats = new RoleDailyStats();

    @Column
    @ColDefine(customType = "longtext")
    private String dailyStatsJson;

    @Column
    private int aitype;


    /**
     * 线程分发id
     */
    private int distributeKey;

    /**
     * 跨服信息
     */
    private CrossInfo crossInfo = new CrossInfo();

    public Role() {
        /**新创建角色的每日重置时间为当前时间，避免下次未过重置时间登录却被重置*/
        dailyFiveResetTime = System.currentTimeMillis();
        gold2money = NutMap.NEW();
    }

    /**
     * 增益属性值
     */
    private int extraSpeed;
    private int extraLife;
    private int extraMana;
    private int extraPhyPower;
    private int extraMagPower;
    private int extraDefense;
    /**
     * 增益相性
     */
    private int extraMetal;
    private int extraWood;
    private int extraWater;
    private int extraFire;
    private int extraEarth;
    /**
     * 增益基础属性
     */
    private int extraWiz;
    private int extraStr;
    private int extraDex;
    private int extraCon;
    /**
     * 强力伤害
     */
    private int extraStrengthPhyRate;
    private int extraStrengthMagRate;
    /**
     * 忽视抗性
     */
    private int ignoreResistMetal;
    private int ignoreResistWood;
    private int ignoreResistWater;
    private int ignoreResistFire;
    private int ignoreResistEarth;
    /**
     * 抗性
     */
    private short resistMetal;//抗金相
    private short resistWood;//抗木相
    private short resistWater;//抗水相
    private short resistFire;//抗火相
    private short resistEarth;//抗土相
    /**
     * 强力障碍
     */
    private short strengthForgotten;
    private short strengthFrozen;
    private short strengthConfusion;
    private short strengthPoison;
    private short strengthSleep;
    /**
     * 忽视抗异常
     */
    private short ignoreResistForgotten;
    private short ignoreResistFrozen;
    private short ignoreResistConfusion;
    private short ignoreResistPoison;
    private short ignoreResistSleep;
    /**
     * 抗异常
     */
    private short resistForgotten;
    private short resistFrozen;
    private short resistConfusion;
    private short resistPoison;
    private short resistSleep;

    private int mStuntRate;//法术必杀
    private int stuntRate;//必杀率
    private int doubleHitRate;//连击率
    private int doubleHit;//连击
    private int dodge;//躲避率
    private int penetrateRate;//破防率
    private int penetrate;//破防
    private short extraSkillLevel;//增益技能等级

    private int damageSel;//反震度
    private int damageSelRate;//反震率

    //上次天神挑战时间
    private long tianshentime=0;


    @Column
    @ColDefine(customType = "longtext")
    private String juntianJson;

    @Column
    private int qisha_type;

    private MSGJiuTianRespMasterInfo msgjuntian = new MSGJiuTianRespMasterInfo();


    public void setBasicAttrib() {
        getExtendBox().setBasicAttrib(new BasicAttrib(level));
    }

    /**
     * 是否是会员
     */
    @JsonIgnore
    public boolean isVip() {
        if (this.getVipType() <= 0) {
            return false;
        }
        return (this.getExpireTime() < 0 ? this.getExpireTime() + 4294967296L : this.getExpireTime()) >= (System.currentTimeMillis() / TimeUtil.ONE_SECOND);
    }

    /**
     * gather类型
     */
    private byte gatherType;

    /**
     * 临时缓存数据
     */
    private transient Map<String, Object> tempCache;

    /**
     * 记录已掉落
     */
    private RoleDrop roleDrop = new RoleDrop();

    @Column
    @ColDefine(customType = "longtext")
    private String roleDropJson;

    /**
     * 供计算在线时长的登录的时间戳，请注意这个时间戳在每天重置时会重置
     */
    private long onlineLoginTime;

    /**
     * 在当前次登录前的所有累计登录时间秒数，每天重置
     */
    @Column
    @Comment("之前累计当天在线时长秒数")
    private int preOnlineSec;

    /**
     * 登录天数
     */
    @Column
    private int loginDays;

    /**
     * 上一移动时间
     */
    private long prevMoveTime;

    /**
     * 心跳包数量，用于检测是否使用加速器
     */
    private Map<Integer, Integer> heartCounts = new HashMap<>(4);

    /**
     * 封号结束时间
     */
    private long blockEndTime;

    /**
     * 充值状态，0 未充值，1 已经充值未领取  2 已经充值已经领取
     */
    @Column
    @Comment("充值状态")
    @Default("0")
    private byte firstPayStatus;


    /**
     * 好友数据
     */
    private FriendBox friendBox = new FriendBox();

    @Column
    @ColDefine(customType = "longtext")
    private String friendBoxJson;


    /**
     * 守护
     */
    private GuardBox guardBox = new GuardBox();

    @Column
    @ColDefine(customType = "longtext")
    private String guardBoxJson;

    /**
     * 离线通知
     */
    private RoleOfflineNotice offlineNotice = new RoleOfflineNotice();

    @Column
    @ColDefine(customType = "longtext")
    private String offlineNoticeJson;


    /**飞升信息*/
    private ChildInfo childInfo =new ChildInfo();
    @Column
    @ColDefine(customType = "longtext")
    private String childJson;


    /**是否是真身*/
    public boolean isRealBody(){
        return childInfo.getState()==0;
    }
    /**
     * 上次战斗结束时间戳
     */
    private long prevFightEndTime;

    /**
     * 上次心跳时间
     */
    private long prevHeartTime;

    /**
     * 上一次推送亲密无间宠物id
     */
    private int lastQinMiPet;
    /**
     * 上次战斗死了还是没死 1没死   0死了
     */
    private int lastDead = 1;


    public void setPos(int x, int y, int dir, int mapId) {
        this.pos.setX((short) x);
        this.pos.setY((short) y);
        this.pos.setDir((byte) dir);
        this.pos.setMapId(mapId);
    }


    public void setSiver(int siver) {
        if (siver > 2000000000) {
            siver = 2000000000;
        }
        if (siver < 0) {
            siver = 0;
        }
        this.siver = siver;
    }

    public void setMoney(int money) {
        if (money > 2000000000) {
            money = 2000000000;
        }
        if (money < 0) {
            money = 0;
        }
        this.money = money;
    }

    public void setVoucher(int voucher) {
        if (voucher > 2000000000) {
            voucher = 2000000000;
        }
        if (voucher < 0) {
            voucher = 0;
        }
        this.voucher = voucher;
    }

    public void setExp(int exp) {
        if (exp > 2000000000) {
            exp = 2000000000;
        } else if (exp < 0) {
            exp = 0;
        }
        this.exp = exp;
    }

    public void setSaveLoyalty(int saveLoyalty) {
        if (saveLoyalty < 0) {
            saveLoyalty = 0;
        }
        this.saveLoyalty = saveLoyalty;
    }
    public boolean isAi(Role role) {
        if(role.getAitype() == 1 || role.getAitype() == 2 ){
            return true;
        }
        return false;
    }

    @Override
    @JsonIgnore
    public Long getId() {
        return uid;
    }

    @JsonIgnore
    public String getGid() {
        return String.valueOf(uid);
    }

    @Override
    public void doAfterInit() {
        PlayerSerializerUtil.deserialize(this);
    }

    @Override
    public void doBeforeSave() {
        PlayerSerializerUtil.serialize(this);
    }

    /**
     * 投递进入库队列
     */
    public void save() {
        if(isAi(this) ){
            return;
        }
        Db4PlayerService.getInstance().add2Queue(this);
    }

    /**
     * 投递进入库队列
     */
    public void aiSave() {
        Db4PlayerService.getInstance().add2Queue(this);
    }

    public RoleActivity getActivity() {
        return activity;
    }

    public int getDistributeKey() {
        return distributeKey;
    }

    public void setDistributeKey(int distributeKey) {
        this.distributeKey = distributeKey;
    }

    /**
     * 临时保存数据
     */
    public Object pushTempCache(String key, Object value) {
        if (tempCache == null) {
            tempCache = new HashMap<>(4);
        }
        return tempCache.put(key, value);
    }

    /**
     * 弹出临时保存数据
     */
    @SuppressWarnings("unchecked")
    public <T> T popTempCache(String key) {
        if (tempCache == null) {
            return null;
        }
        return (T) tempCache.remove(key);
    }

    public <T> T getTempCache(String key, T defaultValue) {
        if (tempCache == null) {
            return defaultValue;
        }
        return (T) tempCache.getOrDefault(key, defaultValue);
    }

    /**取跟随宠物ID*/
    @JsonIgnore
    public int getFollowPetId(){
        return this.getTempCache("followPet", 0);
    }

    @JsonIgnore
    public int getGold() {
        if(!isUnlock() && getSafePasswd()!=null){
            SafeService safeService = SpringUtils.getBean(SafeService.class);
            safeService.sendPasswdInputDlg(this, safeService.getErrorNum(this));
            MessagePusher.pushMessage(this,new RespMsg("当前安全锁未验证,请先到安全锁界面验证安全锁再重试!"));
            throw new IllegalArgumentException("未验证安全锁");
        }
        Account account = SpringUtils.getAccountService().getAccount(getSid());
        return account.getGold();
    }

    /**
     * 取最大法力值
     */
    @JsonIgnore
    public int getMaxMana() {
        int maxMana = SpringUtils.getBean(CountService.class).countMaxMana(this);
        int extraMana = SpringUtils.getBean(CountService.class).countExtraMana(this);
        return maxMana - extraMana + this.extraMana;
    }

    /**
     * 取最大血量
     */
    @JsonIgnore
    public int getMaxLife() {
        int maxLife = SpringUtils.getBean(CountService.class).countMaxLife(this);
        int extraLife = SpringUtils.getBean(CountService.class).countExtraLife(this);
        return maxLife - extraLife + this.extraLife;
    }

    /**
     * 取最大速度
     */
    @JsonIgnore
    public int getMaxSpeed() {
        int maxSpeed = SpringUtils.getBean(CountService.class).countMaxSpeed(this);
        int extraSpeed = SpringUtils.getBean(CountService.class).countExtraSpeed(this);
        return maxSpeed - extraSpeed + this.extraSpeed;
    }

    /**
     * 取最大物攻
     */
    @JsonIgnore
    public int getMaxPhyPower() {
        int maxPhyPower = SpringUtils.getBean(CountService.class).countMaxPhyPower(this);
        int extraPhyPower = SpringUtils.getBean(CountService.class).countExtraPhyPower(this);
        return maxPhyPower - extraPhyPower + this.extraPhyPower;
    }

    /**
     * 取最大法攻
     */
    @JsonIgnore
    public int getMaxMagPower() {
        int maxMagPower = SpringUtils.getBean(CountService.class).countMaxMagPower(this);
        int extraMagPower = SpringUtils.getBean(CountService.class).countExtraMagPower(this);
        return maxMagPower - extraMagPower + this.extraMagPower;
    }

    /**
     * 取最大防御
     */
    @JsonIgnore
    public int getMaxDefense() {
        int maxDefense = SpringUtils.getBean(CountService.class).countMaxDefense(this);
        int extraDefense = SpringUtils.getBean(CountService.class).countExtraDefense(this);
        return maxDefense - extraDefense + this.extraDefense;
    }


    /**
     * 取道行的天数
     */
    @JsonIgnore
    public int getTao() {
        return (int) (taoPoint / Const.ONE_DAY_POINT);
    }

    /**
     * 取道行除去天之后的点数
     */
    @JsonIgnore
    public int getTaoLastPoint() {
        return (int) (taoPoint % Const.ONE_DAY_POINT);
    }

    /**
     * 设置总道行点数
     */
    public void setTaoPoint(long taoPoint) {
        this.taoPoint = taoPoint;
    }


    /**
     * 取月道行天数
     */
    @JsonIgnore
    public int getMonthTao() {
        return (int) (monthTaoPoint / Const.ONE_DAY_POINT);
    }

    /**
     * 取月道行除去天之后的点数
     */
    @JsonIgnore
    public int getMonthTaoLastPoint() {
        return (int) (monthTaoPoint % Const.ONE_DAY_POINT);
    }

    /**
     * 设置月道行点数
     */
    public void setMonthTaoPoint(long monthTaoPoint) {
        this.monthTaoPoint = monthTaoPoint;
    }


    /**
     * 取上月道行天数
     */
    @JsonIgnore
    public int getPrevMonthTao() {
        return (int) (prevMonthTaoPoint / Const.ONE_DAY_POINT);
    }

    /**
     * 取上月道行除去天之后的点数
     */
    @JsonIgnore
    public int getPrevMonthTaoLastPoint() {
        return (int) (prevMonthTaoPoint % Const.ONE_DAY_POINT);
    }

    /**
     * 设置上月道行点数
     */
    public void setPrevMonthTaoPoint(long prevMonthTaoPoint) {
        this.prevMonthTaoPoint = prevMonthTaoPoint;
    }

    public FriendBox getFriendBox() {
        return friendBox;
    }

    public void setFriendBox(FriendBox friendBox) {
        this.friendBox = friendBox;
    }

    public String getFriendBoxJson() {
        return friendBoxJson;
    }

    public void setFriendBoxJson(String friendBoxJson) {
        this.friendBoxJson = friendBoxJson;
    }

    public GuardBox getGuardBox() {
        return guardBox;
    }

    public void setGuardBox(GuardBox guardBox) {
        this.guardBox = guardBox;
    }

    public String getGuardBoxJson() {
        return guardBoxJson;
    }

    public void setGuardBoxJson(String guardBoxJson) {
        this.guardBoxJson = guardBoxJson;
    }

    /**
     * 添加金币
     */
    public void addMoney(int money, Reason reason) {
        if (money < 0) {
            throw new IllegalArgumentException("增加游戏币不能为负数");
        }
       // Logger logger = LoggerFunction.MONEY.getLogger();
        long before = this.money;
        long newMoney = before + money;
        if (newMoney > 2000000000) {
            newMoney = 2000000000;
        }
        this.money = (int) newMoney;
        SpringUtils.getBean(SendAchieve.class).achieveRoleMoneyEvent(this,this.money,"add");
        log.error("addMoney|{}|{}|{}|{}", getId(), before, this.money, reason.getDesc());
    }

    /**
     * 消费金币
     */
    public void costMoney(int money, Reason reason) {
        if (money < 0) {
            throw new IllegalArgumentException("扣除游戏币不能为负数");
        }
        //Logger logger = LoggerFunction.MONEY.getLogger();
        int before = this.money;
        if (before < money) {
            throw new IllegalArgumentException("游戏币不足");
        }
        this.money -= money;
        int oldMoney = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(new Date());
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        String s = redisService.get(format + this.roleId);
        if(StringUtils.isNotEmpty(s)){
            oldMoney = Integer.parseInt(s);
        }
        redisService.set(format + this.roleId,oldMoney+money,60*60*24);
        SpringUtils.getBean(SendAchieve.class).achieveRoleMoneyEvent(this,this.money,"del");
        //MessagePusher.pushMessage(this,new RespNotifyMiscEx("扣除金币"+money));
        log.error("costMoney|{}|{}|{}|{}", getId(), before, this.money, reason.getDesc());
    }

    @JsonIgnore
    public ChangeCard getChangeCard() {
        ChangeCard changeCard = ItemDataPool.name2ChangeCard.get(changeCardName);
        if(changeCard!=null){
            changeCard.setExpireTime(changeCardExpireTime);
        }
        return changeCard;
    }

    public void setChangeCard(ChangeCard changeCard) {
        if (changeCard == null) {
            this.changeCardName = null;
        } else {
            this.changeCardName = changeCard.getName();
            this.changeCardExpireTime =changeCard.getExpireTime();
        }
    }

    @JsonIgnore
    public ShapePen getShapePen() {
        ShapePen shapePen = ItemDataPool.key2ShapePen.get(shapePenKeyName);
        if(shapePen!=null){
            shapePen.setExpireTime(shapePenExpireTime);
        }
        return shapePen;
    }

    public void setShapePen(ShapePen shapePen) {
        if (shapePen == null) {
            this.shapePenKeyName = null;
        } else {
            this.shapePenKeyName = shapePen.getKeyName();
            this.shapePenExpireTime =shapePen.getExpireTime();
        }
    }

    @Override
    public String toString() {
        return "Role{" +
                "uid=" + uid +
                ", name='" + name + '\'' +
                '}';
    }

    @JsonIgnore
    /**获得帮派名称*/
    public String getPartyName() {
        Party party = SpringUtils.getPartyService().getParty(this);
        if (party != null) {
            return party.getPartyName();
        }

        return null;
    }
    //战力
    @Column
    private int fight_cap =0;//战力4931008686
    @Column
    private int fight_cap_total =0;//战力总和
    @Column
    private int fight_cap_without_intimacy;//战力494
    public void setfight_cap(int fight_cap) {
        if (fight_cap > 2000000000) {
            fight_cap = 2000000000;
        } else if (fight_cap < 0) {
            fight_cap = 0;
        }
        this.fight_cap = fight_cap;
    }
    public int getfight_cap() {
        return this.fight_cap;
    }
    public int getfight_cap_total() {
        return this.fight_cap_total;
    }

  //附灵

    @Column
    private int fulingLevel;

    public int getFulingLevel() {
        return this.fulingLevel;
    }

    public void setFulingLevel(int fulingLevel) {
        this.fulingLevel = fulingLevel;
    }

    @Column
    private byte zhenlingType = 0;

    public byte ZhenlingType() {
        return this.zhenlingType;
    }

    public void setZhenlingType(byte zhenlingType) {
        this.zhenlingType = zhenlingType;
    }

    @Column
    private int zhenlingLevel;

    public int getZhenlingLevel() {
        return this.zhenlingLevel;
    }

    public void setZhenlingLevel(int zhenlingLevel) {
        this.zhenlingLevel = zhenlingLevel;
    }


    @Column
    private double qinglong = 1.0;

    public double getQinglong() {
        return this.qinglong;
    }

    public void setQinglong(double qinglong) {
        this.qinglong = qinglong;
    }

    @Column
    private double baihu = 1.0;

    public double getBaihu() {
        return this.baihu;
    }

    public void setBaihu(double baihu) {
        this.baihu = baihu;
    }

    @Column
    private double zhuque = 1.0;

    public double getZhuque() {
        return this.zhuque;
    }

    public void setZhuque(double zhuque) {
        this.zhuque = zhuque;
    }

    @Column
    private double xuanwu = 1.0;

    public double getXuanwu() {
        return this.xuanwu;
    }

    public void setXuanwu(double xuanwu) {
        this.xuanwu = xuanwu;
    }

  //洛书
    @Column
    private short luoshuLevel = 1;

    public short getLuoshuLevel() {
        return this.luoshuLevel;
    }

    public void setLuoshuLevel(short luoshuLevel) {
        this.luoshuLevel = luoshuLevel;
    }

    @Column
    private int luoshuExp;

    public int getLuoshuExp() {
        return this.luoshuExp;
    }

    public void setLuoshuExp(int luoshuExp) {
        this.luoshuExp = luoshuExp;
    }

    @Column
    private int luoshuMagpower;

    public int getLuoshuMagpower() {
        return this.luoshuMagpower;
    }

    public void setLuoshuMagpower(int luoshuMagpower) {
        this.luoshuMagpower = luoshuMagpower;
    }

    @Column
    private int luoshumPhypower;

    public int getLuoshumPhypower() {
        return this.luoshumPhypower;
    }

    public void setLuoshumPhypower(int luoshumPhypower) {
        this.luoshumPhypower = luoshumPhypower;
    }

    @Column
    private int luoshuDefense;

    public int getLuoshuDefense() {
        return this.luoshuDefense;
    }

    public void setLuoshuDefense(int luoshuDefense) {
        this.luoshuDefense = luoshuDefense;
    }

    @Column
    private int luoshuSpeed;

    public int getLuoshuSpeed() {
        return this.luoshuSpeed;
    }

    public void setLuoshuSpeed(int luoshuSpeed) {
        this.luoshuSpeed = luoshuSpeed;
    }

    @Column
    private boolean islingqufuyao;

    public boolean isIslingqufuyao() {
        return this.islingqufuyao;
    }

    public void setIslingqufuyao(boolean islingqufuyao) {
        this.islingqufuyao = islingqufuyao;
    }

    @Column
    private int fuyaoExp;

    public int getFuyaoExp() {
        return this.fuyaoExp;
    }

    public void setFuyaoExp(int fuyaoExp) {
        this.fuyaoExp = fuyaoExp;
    }

    @Column
    private int fuyaoXiaolv = 5;

    public int getFuyaoXiaolv() {
        return this.fuyaoXiaolv;
    }

    public void setFuyaoXiaolv(int fuyaoXiaolv) {
        this.fuyaoXiaolv = fuyaoXiaolv;
    }

    public void setType(int type) {
        this.type = type;
    }

    public void setSub_type(int sub_type) {
        this.sub_type = sub_type;
    }

    public void setVipType(byte vipType) {
        this.vipType = vipType;
    }

    public void setGatherType(byte gatherType) {
        this.gatherType = gatherType;
    }

    public void setMijingjifen(int mijingjifen) {
        this.mijingjifen = mijingjifen;
    }

    public void setMijingcount(int mijingcount) {
        this.mijingcount = mijingcount;
    }

    public void setNice(int nice) {
        this.nice = nice;
    }


    public void setNiceszhi(int niceszhi) {
        this.niceszhi = niceszhi;
    }

    public void setZmLevel(byte zmLevel) {
        this.zmLevel = zmLevel;
    }

    public void setYmType(byte ymType) {
        this.ymType = ymType;
    }


    public int type = -1;

    public int getType() {
        return this.type;
    }

    public int sub_type = -1;


    public int getMijingjifen() {
        return this.mijingjifen;
    }

    public int getMijingcount() {
        return this.mijingcount;
    }


    public int getNice() {
        return this.nice;
    }


    public int getNiceszhi() {
        return this.niceszhi;
    }


    public int getSub_type() {
        return this.sub_type;
    }

    public int getRoleId() {
        return this.roleId;
    }

    public byte getZmLevel() {
        return this.zmLevel;
    }

    public byte getYmType() {
        return this.ymType;
    }



    public byte getVipType() {
        return this.vipType;
    }

    public byte getZhenlingType() {
        return this.zhenlingType;
    }

    public byte getGatherType() {
        return this.gatherType;
    }

    public void setIsHide(int isHide) {
        this.isHide = isHide;
    }

    public int isHide = -1;

    public int getIsHide() {
        return this.isHide;
    }

    public boolean isHideMount() {
        return this.hideMount;
    }
    //结婚
    @Column
    private int loverId = 0;

    public void setLoverId(int loverId) {
        this.loverId = loverId;
    }

    public int getLoverId() {
        return this.loverId;
    }

    @Column
    public int fly_type=1;

    public int getFly_type() {
        return fly_type;
    }

    public void setFly_type(int fly_type) {
        this.fly_type = fly_type;
    }

    // add tao 获取指定类型的RoleEquip
    public RoleEquip getFasionRoleEquip(String type) {
        RoleEquip roleEquip = null;
        for (Map.Entry<Integer, RoleEquip> entry : (Iterable<Map.Entry<Integer, RoleEquip>>) this.getEquipBox().getEquips().entrySet()) {
            RoleEquip tempEquip = entry.getValue();
            if (type.equals("fasion") && tempEquip.getPosition() == 31) {
                roleEquip = tempEquip;
                break;
            }
            if (type.equals("followPet") && tempEquip.getPosition() == 37) {
                roleEquip = tempEquip;
                break;
            }
            if (type.equals("effect") && tempEquip.getPosition() == 32) {
                roleEquip = tempEquip;
                break;
            }
        }
        return roleEquip;
    }
//    // add:e
//    public boolean equals(Object obj) {
//        if (this == obj) return true;
//        if (obj == null || getClass() != obj.getClass()) return false;
//        Role person = (Role) obj;
//        return roleId == person.getRoleId();
//    }
//    @Override
//    public int hashCode() {
//        return Objects.hash(roleId);
//    }
    // add:e
}

